package jmcnet.libcommun.jmcnetds.flex
{
	import flash.utils.getQualifiedClassName;
	
	import jmcnet.libcommun.communs.JMCNetLibCommunHelper;
	import jmcnet.libcommun.logger.JMCNetLogger;
	import jmcnet.libcommun.security.LoginWindow;
	
	import mx.managers.PopUpManager;
	import mx.rpc.IResponder;
	
	public class BaseDelegate implements IResponder
	{
		private var _command : BaseCommand = null;
		
		/**
		 * Classe de base de tous les Delegate. Formalise les callbacks
		 */
		public function BaseDelegate(command : BaseCommand) {
			super();
			if ( getQualifiedClassName(super) == "BaseDelegate" )
            	throw new UninitializedError("La classe BaseDelegate est abstraite et ne peut pas être instanciée"); 
			_command = command;
		}
		
		public function get command():BaseCommand { return _command;}
		
		/**
		 * Appelée lors du retour de l'appel de service
		 */
		 public function result(obj:Object):void {
			JMCNetLogger.info("Appel BaseDelegate:result");
			var retour:XML=null;
			// TODO a remettre ultérieurement pour la gestion des erreurs
			// try {
				retour = obj.result as XML;
				
				// Pour qu'il puisse être utilisé dans la syntaxe : NScommuns::resultat
				var NScommuns:Namespace=JMCNetDSConstantes.NScommuns;
				
				var resultat:XML = retour.NScommuns::resultat[0];
				var data:XML = null;
				try {
					data = retour.*::data[0];
				} catch (err:Error) {
					JMCNetLogger.debug("Pas de data pour le message reçu");
				}
				
				var codeRetour:uint = resultat.NScommuns::codeRetour;
				var cleMessage:String  = resultat.NScommuns::cleMessage;
				var parametres:XMLList = resultat.NScommuns::parametre;
				// default xml namespace = Services.NSnone;
				
				cleMessage = construireMessageComplet(cleMessage, parametres);
					
				switch (codeRetour) {
					case JMCNetDSConstantes.ERR_CODE_OK :
						JMCNetLogger.debug("BaseDelegate:result le retour est OK");
						// On remet le namespace sinon ca bug grave ...
						var ret:Boolean = _command.onResult(data);
						this.callback(ret, data);
						break;
					case JMCNetDSConstantes.ERR_CODE_EXCEPTION_TECHNIQUE :
						JMCNetLogger.warn("BaseDelegate:result Erreur Technique : codeRetour="+codeRetour+" message="+cleMessage);
						_command.onTechnicalError(new Error(cleMessage), retour);
						callback(false, retour);
						break;
					case JMCNetDSConstantes.ERR_CODE_LOGIN_NEDEED :
						JMCNetLogger.warn("BaseDelegate:result Demande de login ... Please logon... ");
						// Demande de login
						var loginWin:LoginWindow = PopUpManager.createPopUp(JMCNetLibCommunHelper.mainAppDisplay,LoginWindow, true) as LoginWindow;
						PopUpManager.centerPopUp(loginWin);
						
						// Pour que l'on soit rappeler lorsque le login est OK avec le resultat de l'appel du service
						loginWin.responderWhenOk = this.result;
						loginWin.responderWhenKo = this.fault;
						// _command.onTechnicalError(new Error(cleMessage), retour);
						// callback(false, retour);
						break;
					case JMCNetDSConstantes.ERR_CODE_SESSION_EXPIRED :
						JMCNetLogger.warn("BaseDelegate:result La session a expirée. -> on informe par une erreur technique");
						_command.onTechnicalError(new Error(cleMessage), retour);
						callback(false, retour);
						break;
					default :
						JMCNetLogger.warn("BaseDelegate:result Erreur fonctionnelle : codeRetour="+codeRetour+" message="+cleMessage);
						_command.onFonctionnalError(codeRetour, new Error(cleMessage), retour);
						callback(false, retour);
						break;
				}
//			} catch (err:Error) {
//				_command.onTechnicalError(err, retour);
//				this.callback(false, retour);
//			}
		}
		
		private function construireMessageComplet (cleMessage:String, parametres:XMLList):String {
			if (parametres != null) {
				cleMessage += "(";
				for (var i:uint = 0; i < parametres.length() ; i++) {
					var parametre:XML = parametres[i];
					cleMessage += parametre.toString() + ",";
				}
				
				// On enlève la dernière virgule
				cleMessage = cleMessage.substr(0, cleMessage.length - 1);
				cleMessage += ")";
			}
			
			return cleMessage;
		}
		
		public function fault(info:Object):void	{
			JMCNetLogger.error("BaseDelegate:fault erreur="+info.toString());
			_command.onTechnicalError(new Error(info.toString()), null);
			this.callback(false, info);
		}
		
		protected function callback(ok:Boolean, data:Object):void {
			if (_command.event != null) {
				_command.event.callback(ok, data);
			}
		}
	}
}